define(['./FormPlugin',
        '../../lib/xml2json',   
        './ActionJScript',     
        './models/FormPage',
        './models/FormWidget',
        './models/FormWidget_Combo',
        './models/FormWidget_List',
        './models/FormWidget_Radio',
        './models/FormWidget_PushBtn',
        './models/FormWidget_Text',
        './models/FormWidget_Check',
        './models/FormWidgetType'
    ],
    function(FormPlugin,
        X2JS,
        ActionJScript,
        FormPage,
        FormWidget,
        FormWidget_Combo,
        FormWidget_List,
        FormWidget_Radio,
        FormWidget_PushBtn,
        FormWidget_Text,
        FormWidget_Check,
        FormWidgetType) {
        'use strict';

        FormPlugin.factory('FormService', ['$http', '$q', '$compile', 'PDFConfig',
            function($http, $q, $compile, PDFConfig) {
                var _baseUrl = '/app/pdfdata/';
                var _requiredFieldXml = null;
                var _fromPages = {};

                var _formItemValues = {};
                var _itemsCheckRadioBoxDefaultOff = {};//用于标识CheckBox、RadioBox的Off值默认
                var dnmmy = $("body");

                var runPDFJS = ActionJScript.init({
            
                    getItemValue: _getItemValue,
                    alert: function(string){
                        console.log(string);
                    }
                });

                function makeEventName(str){
                    //事件名称中不能包含空格和.,转为_
                    return trim(str).replace(/\s+/g, "_").replace(/\./g, '_');       
                }

                function _setItemValue(itemName, itemValue) {                            
                   if (_formItemValues.hasOwnProperty(itemName)){
                        _formItemValues[itemName].value = itemValue;                                            
                   }
                   else{                        
                        _formItemValues[itemName] = {'origValue': null, 'value': itemValue};      
                   }
                   dnmmy.trigger(makeEventName(itemName), [itemValue]);
                   return true;
                }

                function _setItemOrigValue(itemName, itemValue){
                    if (_formItemValues.hasOwnProperty(itemName)) {
                        if(_formItemValues[itemName].origValue === null){                            
                            _formItemValues[itemName].origValue = itemValue;
                        }                        
                    } else {
                        _formItemValues[itemName] = {'origValue': itemValue, 'value': itemValue};
                        dnmmy.trigger(makeEventName(itemName), [itemValue]);     
                    }
                }

                function _getItemValue(itemName) {
                    if (_formItemValues.hasOwnProperty(itemName)){
                       return _formItemValues[itemName].value;
                    }
                    return null;                    
                }

                function _getItemOrigValue(itemName) {
                    if (_formItemValues.hasOwnProperty(itemName)){
                       return _formItemValues[itemName].origValue;
                    }
                    return null;                    
                }                        

                function _onItemValueChange(itemNames, func) {                  
                    if (typeof func == "function") {    
                        if ($.isArray(itemNames)){
                            var eventNames = [];
                            for(var i = 0; i < itemNames.length; i++){
                                eventNames.push(makeEventName(itemNames[i]));
                            }
                            itemNames = eventNames.join(" ");
                        }              
                        else{
                            itemNames = makeEventName(itemNames);
                            func(_getItemValue(itemNames));
                        }                               
                        dnmmy.on(itemNames, function(event, data){
                           func(data);
                        });                                         
                    } 
                }

                function _getRequiredFieldXml() {
                    var deferred = $q.defer();
                    var formXmlUrl = _baseUrl + PDFConfig.s3Key + "/form_requiredfield_xmldata";
                    $http.get(formXmlUrl)
                        .success(function(data) {
                            _requiredFieldXml = data;
                            deferred.resolve(_requiredFieldXml);
                        })
                        .error(function(data) {
                            deferred.reject('there was an error');
                        });
                    _requiredFieldXml =  deferred.promise;
                    return _requiredFieldXml;
                }


                function _setFormDataByXML(xmlData) {
                    var x2js = new X2JS();                      
                    var jsonData = x2js.xml_str2json(xmlData);
                    for(var key in jsonData.fields){
                        if (jsonData.fields.hasOwnProperty(key)){
                            var formField = jsonData.fields[key];
                            if ($.isPlainObject(formField)){                              
                                var name = getNodeString(formField, 'xfdf:original');
                                var value = formField.toString();
                                _setItemValue(name, value);                            
                            }
                        }
                    }                  
                }

                function _getFormPageFromService(pageIndex) {                
                    var deferred = $q.defer();
                    var formXmlUrl = _baseUrl + PDFConfig.s3Key + "/form_xmldata_" + pageIndex;
                    var req = {
                        method: 'GET',
                        url: formXmlUrl,
                        //dataType: 'xml',
                        contentType: "application/x-www-form-urlencoded",
                    };
                    $http(req)
                        .success(function(data) {
                            var cur = new Date().getTime();
                            var formPage = _parseToFormPage(pageIndex, data);
                            _fromPages[pageIndex] = formPage;
                            deferred.resolve(_fromPages[pageIndex]);
                        })
                        .error(function(data) {
                            deferred.reject('there was an error');
                        });                    
                    _fromPages[pageIndex] = deferred.promise;
                    return _fromPages[pageIndex];
                }

                function trim(str) {
                    //删除左右两端的空格
                    return str.replace(/(^\s*)|(\s*$)/g, '');
                }          

                
                function getNodeFloat($obj, item_name) {
                    var ret = 0;
                    if ($obj && (typeof($obj["_" + item_name]) != 'undefined')) {
                        ret = parseFloat($obj["_" + item_name]);
                    }
                    return ret;
                }

                function getNodeInt($obj, item_name) {
                    return parseInt(getNodeFloat($obj, item_name));
                }

                function getNodeString($obj, item_name) {
                    var ret = '';
                    if ($obj && (typeof($obj["_" + item_name]) != 'undefined')) {
                        ret = $obj["_" + item_name];
                    }
                    return ret;
                }


                function createWidget(wiget, formPage) {
                    if (!wiget || !formPage) return null;
                    var type = getNodeInt(wiget, 'Type');
                    if (type == FormWidgetType.PushButton) {
                        return _parseToFormWidget_PushBtn(formPage, wiget);
                    } else if (type == FormWidgetType.RadioButton) {
                        return _parseToFormWidget_Radio(formPage, wiget);
                    } else if (type == FormWidgetType.CheckBox) {
                        return _parseToFormWidget_Check(formPage, wiget);
                    } else if (type == FormWidgetType.Text || type == FormWidgetType.RichText) {
                        return _parseToFormWidget_Text(formPage, wiget);
                    } else if (type == FormWidgetType.ListBox) {
                        return _parseToFormWidget_List(formPage, wiget);
                    } else if (type == FormWidgetType.ComboBox) {
                        return _parseToFormWidget_Combo(formPage, wiget);
                    }
                    else{
                        throw "an identifiableformWidget type";
                    }
                }                

                var ARG_ARRAY = /\s*new Array\s*[^\(]*\(\s*([^\)]*)\)/m;
                var ARG_FIELD = /\s*getField\s*[^\(]*\(\s*([^\)]*)\)/mg;
                function addAction(key, action, formWidget) {
                    action = action.replace(/\/\*{1,2}[\s\S]*?\*\//, "");
                    if (key == "C") {
                        var itemNames = [];
                        var argDecl = action.match(ARG_ARRAY);
                        if (argDecl && argDecl.length > 1) {
                            itemNames = argDecl[1].replace(/\"/g, "").split(",");
                        } else {
                            argDecl = ARG_FIELD.exec(action);                          
                            while (argDecl) {
                                itemNames.push(argDecl[1].replace(/\"/g, ""));
                                argDecl = ARG_FIELD.exec(action);
                            }
                        }                      
                        _onItemValueChange(itemNames, function() {                    
                            var ret = runPDFJS(action);             
                            _setItemValue(formWidget.name, ret.value);                                        
                        });
                    }
                    if (key == "F") {
                        formWidget.addFormatter(function(srcValue) {            
                            return runPDFJS(action, null, srcValue).value;
                        });
                    }

                    if (key == "V") {
                        formWidget.addValidater(function(srcValue, element) {
                            return (runPDFJS(action, element, srcValue).rc !== false);
                        });
                    }
                }

                function _getRegisterActionCode(formWidget) {                  
                    var fieldAction = formWidget.fieldAction;
                    if (formWidget.type == FormWidgetType.Text || formWidget.type == FormWidgetType.RichText) {
                        for (var key in fieldAction) {
                            var ht_aas = fieldAction[key];
                            for (var j = 0; j < ht_aas.length; j++) {
                                if (ht_aas[j]) {
                                    var action = ht_aas[j];
                                    if (action === "") continue;
                                    addAction(key, action, formWidget);
                                }
                            }
                        }
                    }
                }
                function _parseToFormPage(pageIndex, xmlData) {                  
                    var formPage = new FormPage();
                    formPage.pageIndex = pageIndex;
                    var x2js = new X2JS();
                    //var Pages = x2js.xml_str2json(xmlStr).Pages;              
                    var jsonData = x2js.xml_str2json(xmlData);
                    var Pages = null;
                    if(jsonData.Pages){
                        Pages = jsonData.Pages;
                    }
                    else{
                        Pages =  {Page: jsonData.Page};
                    }                    
                    
                    formPage.imgUrl = PDFConfig.baseUrl + PDFConfig.s3Key + '/formpage_bg_' + pageIndex;
                    if ($.isPlainObject(Pages.Page)) {
                        Pages.Page = [Pages.Page];
                    }                   
                   
                    $.each(Pages.Page, function() {
                        var page = this;
                        var state = page.State;
                        if (state) {
                            formPage.rotate = getNodeInt(state, '_Rotate');
                            formPage.pdfRect.setValue(getNodeFloat(state, 'l'), getNodeFloat(state, 'b'), getNodeFloat(state, 'Width'), getNodeFloat(state, 'Height'));
                            if (state.Ap && $.isPlainObject(state.Ap)) {
                                formPage.imgPos = getNodeFloat(state.Ap, 'Path');
                            }
                        }

                        var imgInfo = page.ImgInfo;
                        if (imgInfo) {
                            formPage.allImgWidth = getNodeFloat(imgInfo, 'Width');
                            formPage.allImgHeight = getNodeFloat(imgInfo, 'Height');
                        }

                        switch (formPage.rotate) {
                            case 1:
                            case 3:
                                //90 or 270
                                {
                                    formPage.pageHeight = formPage.pdfRect.width;
                                    formPage.pageWidth = formPage.pdfRect.height;
                                }
                                break;
                            default:
                                //0 or 180
                                {
                                    formPage.pageHeight = formPage.pdfRect.height;
                                    formPage.pageWidth = formPage.pdfRect.width;
                                }
                        }

                        var form = page.Form;
                        if (form) {
                            if ($.isPlainObject(form.Widget)){
                                form.Widget = [form.Widget];
                            }                            
                            $.each(form.Widget, function(index) {
                                var formWidget = createWidget(this, formPage);    
                                _getRegisterActionCode(formWidget);
                                formPage.insertFormWidget(formWidget);
                            });

                            formPage.sortFormWidget();        

                        }
                    });                  
                    return formPage;
                }

                function _parseToFormWidget(formPage, widget) {
                    var formWidget = new FormWidget();
                    formWidget.formPage = formPage;

                    if (widget.Pos) {
                        formWidget.rect = formPage.transform(getNodeFloat(widget.Pos, 'l'), getNodeFloat(widget.Pos, 'b'),
                            getNodeFloat(widget.Pos, 'w'), getNodeFloat(widget.Pos, 'h'));
                    }

                    if (widget.General) {
                        if (widget.General.ReadOnly) {
                            formWidget.bReadOnly = trim(widget.General.ReadOnly) == '1' ? true : false;
                        }
                        if (widget.General.Required) {
                            formWidget.bRequired = trim(widget.General.Required) == '1' ? true : false;
                        }
                    }

                    if (widget.Ap) {
                        if (widget.Ap.Font) {
                            formWidget.fontSize = getNodeFloat(widget.Ap.Font, 'FontSize');
                        }
                        if (widget.Ap.BS) {
                            if (widget.Ap.BS.W) {
                                formWidget.borderWidth = parseFloat(widget.Ap.BS.W);
                            }
                        }
                    }

                    formWidget.name = getNodeString(widget, 'Name');
                    formWidget.type = getNodeInt(widget, 'Type');

                    if (widget.AA && $.isPlainObject(widget.AA)) {
                        for (var key in widget.AA) {
                            var ht_fildAAs = [];
                            var count = 0;
                            var AAs = widget.AA[key];

                            for (var aa in AAs) {
                                var value = AAs[aa];
                                if (value) {
                                    ht_fildAAs[count++] = value;
                                }
                            }
                            formWidget.fieldAction[key] = ht_fildAAs;
                        }
                    }
                    
                    formWidget.tabNum = (formPage.pageIndex + 1) * 300 + parseInt(widget.TabOrder);                   
                    return formWidget;
                }

                //_PushBtn
                function _parseToFormWidget_PushBtn(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_PushBtn = new FormWidget_PushBtn(_parseToFormWidget(formPage, widget));

                    formWidget_PushBtn.value = widget.Value;

                    if (widget.Ap) {
                        if (widget.Ap.N) {
                            formWidget_PushBtn.NImgPos = getNodeFloat(widget.Ap.N, 'Path');
                        }
                        if (widget.Ap.R) {
                            formWidget_PushBtn.RImgPos = getNodeFloat(widget.Ap.R, 'Path');
                        }
                        if (widget.Ap.D) {
                            formWidget_PushBtn.DImgPos = getNodeFloat(widget.Ap.D, 'Path');
                        }
                    }

                    return formWidget_PushBtn;
                }

                //_Check
                function _parseToFormWidget_Check(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_Check = new FormWidget_Check(_parseToFormWidget(formPage, widget));

                    formWidget_Check.value = widget.Value;

                    if (widget.State) {
                        if (widget.State.Checked) {
                            formWidget_Check.bCheck = getNodeInt(widget.State.Checked, 'Checked') > 0 ? true : false;
                        }
                    }

                    if (widget.Ap) {
                        if (widget.Ap.N) {
                            if (widget.Ap.N.Off) {
                                formWidget_Check.offImgPos = getNodeFloat(widget.Ap.N.Off, 'Path');
                            }

                            if (widget.Ap.N.On) {
                                formWidget_Check.onImgPos = getNodeFloat(widget.Ap.N.On, 'Path');
                            }
                        }
                    }

                    if(formWidget_Check.bCheck){
                        _setItemOrigValue(formWidget_Check.name, formWidget_Check.value);
                    }
                   
                    return formWidget_Check;
                }

                //_Text
                function _parseToFormWidget_Text(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_Text = new FormWidget_Text(_parseToFormWidget(formPage, widget));
                    if (formWidget_Text.borderWidth === 0) {
                        formWidget_Text.borderWidth = 1;
                    }

                    formWidget_Text.value = widget.Value;

                    if (widget.Flags) {
                        if (widget.Flags.MultiLine) {
                            formWidget_Text.bMultiLine = trim(widget.Flags.MultiLine) == '1' ? true : false;
                        }
                        if (widget.Flags.SpellCheck) {
                            formWidget_Text.bSpellCheck = trim(widget.Flags.SpellCheck) == '1' ? true : false;
                        }
                    }

                    if (widget.Ap) {
                        if (widget.Ap.N) {
                            formWidget_Text.imgPos = getNodeFloat(widget.Ap.N, 'Path');
                        }
                    }

                    if (widget.IsPassword){
                        formWidget_Text.isPassword = trim(widget.IsPassword) == '1' ? true : false;
                    }


                    _setItemOrigValue(formWidget_Text.name, formWidget_Text.value);
                    
                    return formWidget_Text;
                }

                //_List
                function _parseToFormWidget_List(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_List = new FormWidget_List(_parseToFormWidget(formPage, widget));

                    if (widget.Options) {
                        var index = 0;
                        if ($.isPlainObject(widget.Options.Option)){
                            widget.Options.Option = [widget.Options.Option];   
                        }
                        var valueArr = [];
                        $.each(widget.Options.Option, function() {
                            var option = {};                          
                            option.text = this.toString();
                            option.realValue = getNodeString(this, 'realValue');
                            if (option.realValue === '') {
                                option.realValue = option.text;
                            }
                            option.bSelected = getNodeInt(this, 'Selected') > 0 ? true : false;
                            formWidget_List.options[index] = option;
                            index++;

                            if (option.bSelected) {
                                valueArr.push(option.realValue);                                
                            }
                        });
                        formWidget_List.value = valueArr.join(";");
                    }

                    if (widget.Flags && $.isPlainObject(widget.Flags)) {
                        if (widget.Flags.MultiSelect) {
                            formWidget_List.bMultiple = trim(widget.Flags.MultiSelect) == '1' ? true : false;
                        }
                    }

                    if (widget.Ap && $.isPlainObject(widget.Ap)) {
                        if (widget.Ap.N && $.isPlainObject(widget.Ap.N)) {
                            formWidget_List.imgPos = getNodeFloat(widget.Ap.N, 'Path');
                        }
                    }

                    console.log(formWidget_List.name, formWidget_List.value)
                    _setItemOrigValue(formWidget_List.name, formWidget_List.value);
                    return formWidget_List;
                }

                //_Combo
                function _parseToFormWidget_Combo(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_Combo = new FormWidget_Combo(_parseToFormWidget(formPage, widget));
                    if (widget.Options) {
                        var index = 0;
                        if ($.isPlainObject(widget.Options.Option)){
                            widget.Options.Option = [widget.Options.Option];   
                        }
                        $.each(widget.Options.Option, function() {
                            var option = {};
                            option.text = this.toString();
                            option.realValue = getNodeString(this, 'realValue');
                            if (option.realValue === '') {
                                option.realValue = option.text;
                            }
                            option.bSelected = getNodeInt(this, 'Selected') > 0 ? true : false;
                            formWidget_Combo.options[index] = option;
                            index++;
                            if (option.bSelected) {
                                formWidget_Combo.selectValue = option.realValue;
                                formWidget_Combo.selectText = option.text;
                            }
                        });
                    }

                    formWidget_Combo.value = trim(widget.Value);


                    if (widget.General) {
                        if (widget.General.Edit) {
                            formWidget_Combo.bEdit = trim(widget.General.Edit) == '1' ? true : false;
                        }
                    }

                    if (widget.Ap) {
                        if (widget.Ap.N) {
                            formWidget_Combo.imgPos = getNodeFloat(widget.Ap.N, 'Path');
                        }
                    }

                    return formWidget_Combo;
                }

                //_Radio
                function _parseToFormWidget_Radio(formPage, widget) {
                    if (!formPage || !widget) return null;
                    var formWidget_Radio = new FormWidget_Radio(_parseToFormWidget(formPage, widget));


                    formWidget_Radio.value = widget.Value;


                    if (widget.State) {
                        if (widget.State.Checked) {
                            formWidget_Radio.bCheck = getNodeInt(widget.State.Checked, 'Checked') > 0 ? true : false;
                        }
                        if (widget.State.Unison) {
                            formWidget_Radio.bRadiosInUnison = getNodeInt(widget.State.Unison, 'Unison') > 0 ? true : false;
                        }
                    }

                    //获取bNoToggleToOff标志**待完善
                    if (widget.Ap) {
                        if (widget.Ap.N) {
                            if (widget.Ap.N.Off) {
                                formWidget_Radio.offImgPos = getNodeFloat(widget.Ap.N.Off, 'Path');
                            }

                            if (widget.Ap.N.On) {
                                formWidget_Radio.onImgPos = getNodeFloat(widget.Ap.N.On, 'Path');
                            }
                        }
                    }

                    if(formWidget_Radio.bCheck){
                        _setItemOrigValue(formWidget_Radio.name, formWidget_Radio.value);
                    }              

                    return formWidget_Radio;
                }

                function _resetForm() {
                    
                };

                return {
                    getFormRequiredFieldXml: function() {                      
                        if (!_requiredFieldXml) {
                             return _getRequiredFieldXml();                               
                        } else {
                            return $q.when(_requiredFieldXml);
                        }                        
                    },

                    getFormPage: function(pageIndex) {                       
                        if (!_fromPages[pageIndex]) {
                            return _getFormPageFromService(pageIndex);                                
                        } else {
                            return $q.when(_fromPages[pageIndex]);
                        }                      
                    },
                    setItemValue: _setItemValue,
                    getItemValue: _getItemValue,
                    getItemOrigValue: _getItemOrigValue,
                    setItemOrigValue: _setItemOrigValue,
                    onItemValueChange: _onItemValueChange,
                    setFormDataByXML : _setFormDataByXML,
                    resetForm : _resetForm,
                };
            }
        ]);        
    });